package com.luo.backend.service;

import com.luo.backend.dto.AdminOverviewStatisticsResponse;
import com.luo.backend.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 管理员-统计服务
 */
@Service
public class AdminStatisticsService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private MerchantRepository merchantRepository;
    
    @Autowired
    private FoodRepository foodRepository;
    
    @Autowired
    private OrderRepository orderRepository;
    
    /**
     * 获取平台概览统计
     */
    public AdminOverviewStatisticsResponse getOverviewStatistics() {
        AdminOverviewStatisticsResponse response = new AdminOverviewStatisticsResponse();
        
        // 用户统计
        response.setUserStats(getUserStatistics());
        
        // 商家统计
        response.setMerchantStats(getMerchantStatistics());
        
        // 订单统计
        response.setOrderStats(getOrderStatistics());
        
        // 营收统计
        response.setRevenueStats(getRevenueStatistics());
        
        return response;
    }
    
    /**
     * 用户统计
     */
    private AdminOverviewStatisticsResponse.UserStats getUserStatistics() {
        AdminOverviewStatisticsResponse.UserStats stats = 
            new AdminOverviewStatisticsResponse.UserStats();
        
        // 总用户数（排除admin）
        stats.setTotalUsers(userRepository.countByRoleNot("admin"));
        
        // 顾客数量
        stats.setCustomerCount(userRepository.countByRole("customer"));
        
        // 商家数量
        stats.setMerchantCount(userRepository.countByRole("merchant"));
        
        // 活跃用户数（状态为1）
        stats.setActiveUsers(userRepository.countByStatusAndRoleNot(1, "admin"));
        
        // 今日新增用户
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
        long todayNewUsers = userRepository.count((Specification<com.luo.backend.entity.User>) (root, query, cb) -> 
            cb.between(root.get("createdAt"), todayStart, todayEnd)
        );
        stats.setTodayNewUsers(todayNewUsers);
        
        // 本周新增用户
        LocalDateTime weekStart = LocalDateTime.of(LocalDate.now().minusDays(6), LocalTime.MIN);
        long weekNewUsers = userRepository.count((Specification<com.luo.backend.entity.User>) (root, query, cb) -> 
            cb.between(root.get("createdAt"), weekStart, todayEnd)
        );
        stats.setWeekNewUsers(weekNewUsers);
        
        return stats;
    }
    
    /**
     * 商家统计
     */
    private AdminOverviewStatisticsResponse.MerchantStats getMerchantStatistics() {
        AdminOverviewStatisticsResponse.MerchantStats stats = 
            new AdminOverviewStatisticsResponse.MerchantStats();
        
        // 总商家数
        stats.setTotalMerchants(merchantRepository.count());
        
        // 营业中商家
        stats.setActiveMerchants(merchantRepository.countByStatus(1));
        
        // 休息中商家
        stats.setClosedMerchants(merchantRepository.countByStatus(0));
        
        // 总商品数
        stats.setTotalFoods(foodRepository.count());
        
        // 上架商品数
        long activeFoods = foodRepository.count((Specification<com.luo.backend.entity.Food>) (root, query, cb) -> 
            cb.equal(root.get("status"), 1)
        );
        stats.setActiveFoods(activeFoods);
        
        return stats;
    }
    
    /**
     * 订单统计
     */
    private AdminOverviewStatisticsResponse.OrderStats getOrderStatistics() {
        AdminOverviewStatisticsResponse.OrderStats stats = 
            new AdminOverviewStatisticsResponse.OrderStats();
        
        // 总订单数
        stats.setTotalOrders(orderRepository.count());
        
        // 待支付订单
        long pendingOrders = orderRepository.count((Specification<com.luo.backend.entity.Order>) (root, query, cb) -> 
            cb.equal(root.get("status"), "pending")
        );
        stats.setPendingOrders(pendingOrders);
        
        // 处理中订单（paid + preparing + shipping）
        long paidCount = orderRepository.count((Specification<com.luo.backend.entity.Order>) (root, query, cb) -> 
            cb.equal(root.get("status"), "paid")
        );
        long preparingCount = orderRepository.count((Specification<com.luo.backend.entity.Order>) (root, query, cb) -> 
            cb.equal(root.get("status"), "preparing")
        );
        long shippingCount = orderRepository.count((Specification<com.luo.backend.entity.Order>) (root, query, cb) -> 
            cb.equal(root.get("status"), "shipping")
        );
        stats.setProcessingOrders(paidCount + preparingCount + shippingCount);
        
        // 已完成订单
        long completedOrders = orderRepository.count((Specification<com.luo.backend.entity.Order>) (root, query, cb) -> 
            cb.equal(root.get("status"), "delivered")
        );
        stats.setCompletedOrders(completedOrders);
        
        // 已取消订单
        long cancelledOrders = orderRepository.count((Specification<com.luo.backend.entity.Order>) (root, query, cb) -> 
            cb.equal(root.get("status"), "cancelled")
        );
        stats.setCancelledOrders(cancelledOrders);
        
        // 今日订单
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
        long todayOrders = orderRepository.count((Specification<com.luo.backend.entity.Order>) (root, query, cb) -> 
            cb.between(root.get("createdAt"), todayStart, todayEnd)
        );
        stats.setTodayOrders(todayOrders);
        
        // 本周订单
        LocalDateTime weekStart = LocalDateTime.of(LocalDate.now().minusDays(6), LocalTime.MIN);
        long weekOrders = orderRepository.count((Specification<com.luo.backend.entity.Order>) (root, query, cb) -> 
            cb.between(root.get("createdAt"), weekStart, todayEnd)
        );
        stats.setWeekOrders(weekOrders);
        
        return stats;
    }
    
    /**
     * 营收统计
     */
    private AdminOverviewStatisticsResponse.RevenueStats getRevenueStatistics() {
        AdminOverviewStatisticsResponse.RevenueStats stats = 
            new AdminOverviewStatisticsResponse.RevenueStats();
        
        // 总营收（已完成订单）
        BigDecimal totalRevenue = orderRepository.sumTotalAmountByStatus("delivered");
        stats.setTotalRevenue(totalRevenue != null ? totalRevenue : BigDecimal.ZERO);
        
        // 今日营收
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);
        BigDecimal todayRevenue = sumOrderAmountByDateRange(todayStart, todayEnd, "delivered");
        stats.setTodayRevenue(todayRevenue);
        
        // 本周营收
        LocalDateTime weekStart = LocalDateTime.of(LocalDate.now().minusDays(6), LocalTime.MIN);
        BigDecimal weekRevenue = sumOrderAmountByDateRange(weekStart, todayEnd, "delivered");
        stats.setWeekRevenue(weekRevenue);
        
        // 本月营收
        LocalDateTime monthStart = LocalDateTime.of(
            LocalDate.now().withDayOfMonth(1), 
            LocalTime.MIN
        );
        BigDecimal monthRevenue = sumOrderAmountByDateRange(monthStart, todayEnd, "delivered");
        stats.setMonthRevenue(monthRevenue);
        
        // 平均订单金额
        long completedOrderCount = orderRepository.count((Specification<com.luo.backend.entity.Order>) (root, query, cb) -> 
            cb.equal(root.get("status"), "delivered")
        );
        if (completedOrderCount > 0) {
            BigDecimal avgAmount = stats.getTotalRevenue()
                .divide(BigDecimal.valueOf(completedOrderCount), 2, RoundingMode.HALF_UP);
            stats.setAvgOrderAmount(avgAmount);
        } else {
            stats.setAvgOrderAmount(BigDecimal.ZERO);
        }
        
        return stats;
    }
    
    /**
     * 计算指定日期范围内的订单总额
     */
    private BigDecimal sumOrderAmountByDateRange(
            LocalDateTime start, 
            LocalDateTime end, 
            String status) {
        
        List<com.luo.backend.entity.Order> orders = orderRepository.findAll(
            (Specification<com.luo.backend.entity.Order>) (root, query, cb) -> {
                List<Predicate> predicates = new ArrayList<>();
                predicates.add(cb.between(root.get("createdAt"), start, end));
                predicates.add(cb.equal(root.get("status"), status));
                return cb.and(predicates.toArray(new Predicate[0]));
            }
        );
        
        return orders.stream()
            .map(com.luo.backend.entity.Order::getTotalAmount)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
}

